<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>

<body>
  <svg id="svg"></svg>
</body>

</html>
<script src="http://d3js.org/d3.v6.min.js"></script>
<script>
  let width = 400,
    height = 400;
  let colorAry = d3.schemeCategory10;
  let svg = d3.select('#svg').attr('width', width).attr('height', height);
  let main = svg.append('g').classed('main', true)
    .attr('transform', `translate(${width/2},${height/2})`)

  let data = [{
      name: '购物',
      value: 983
    },
    {
      name: '日常饮食',
      value: 300
    },
    {
      name: '医药',
      value: 1400
    },
    {
      name: '交通',
      value: 402
    },
    {
      name: '杂费',
      value: 134
    }
  ]
  
  // 设置弧的半径
  let radius = 100;
  let arc = d3.arc().innerRadius(0).outerRadius(radius).cornerRadius(5) // 得到的是一个生成弧的方法

  // 获取原始数据对应弧 数据
  let pieData = d3.pie().value(d => d.value).sort(null)(data)
  console.log(pieData)
  // 添加文字
  let textArc = d3.arc().innerRadius(0).outerRadius(radius * 3); // 得到的是一个生成弧的方法
  let textgs = main.append('g').attr('class', 'textgs'); // 所有文字的容器
  let texts = textgs.selectAll('text')
    .data(pieData)
    .enter()
    .append('text')
    .attr('fill', (item, index) => colorAry[index])
    .text(d => d.data.name)
    .attr('transform', function (item, index) {
      console.log(textArc.centroid(item))
      let position = textArc.centroid(item);
      return `translate(${position})`
    })
    .attr('text-anchor', function (item, index) {
      // return 'start'  'end'
      if (item.startAngle + (item.endAngle - item.startAngle) / 2 > Math.PI) {
        return 'end'
      } else {
        return 'start'
      }
    })

  // 添加线
  // let lineArc = d3.arc().innerRadius(0).outerRadius(radius*3);// 得到的是一个生成弧的方法
  let linegs = main.append('g').attr('class', 'linegs'); // 所有文字的容器
  let lines = linegs.selectAll('polyline')
    .data(pieData)
    .enter()
    .append('polyline')
    .attr('stroke', (item, index) => colorAry[index])
    // .attr('points',function(item,index){
    //   return [lineArc(item)]
    // })
    .attr('points', function (item, index) {
      let endPoint = textArc.centroid(item);
      if (item.startAngle + (item.endAngle - item.startAngle) / 2 > Math.PI) {
        endPoint[0] -= 20;
      } else {
        endPoint[0] += 20;
      }
      endPoint[1] += 5

      return [arc.centroid(item), [textArc.centroid(item)[0], textArc.centroid(item)[1] + 5], endPoint]
    })
    .attr('fill', 'none')
    .attr('stroke-dasharray', 5)

  //  console.log(arc)

  let slices = main.append('g').attr('class', 'slices'); // 所有弧的容器

  let arcs = slices.selectAll('path')
    .data(pieData)
    .enter()
    .append('path')
    .attr('fill', function (item, index) {
      item.padAngle  = 0.05
      return colorAry[index]
    })
    .attr('d', function (item) {
      // console.log(item,arc(item))
      return arc(item)
    })
    .on('mouseover', function (e, d) {
      let path = d3.select(this);
      path.transition(200).attr('fill', 'pink')
      .attrTween('d',function(data){
        let i = d3.interpolate(radius,radius+30);
        return function(time){
          console.log(time)
          let arc = d3.arc().innerRadius(0).outerRadius(i(time)).cornerRadius(5);
          return arc(data)
        }
      })
    })
    .on('mouseout', function (e, d) {
      let path = d3.select(this);
      path.transition(200).delay(200).attr('fill', colorAry[d.index])
      .attrTween('d',function(d){
        let i = d3.interpolate(radius+30,radius);
        return function(t){
          // console.log(i(t))
          let arc = d3.arc().innerRadius(0).outerRadius(i(t)).cornerRadius(5);
          return arc(d)
        }
      })
    })
</script>